#include <s32strm.h>

#include "PinQModel.h"
#include "PinQTask.h"
#include "PinQCategory.h"
#include "PinQ.hrh"

CPinQModel* CPinQModel::NewL()
	{
	CPinQModel* self = new (ELeave) CPinQModel();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

CPinQModel::CPinQModel()
	{
	}

void CPinQModel::ConstructL()
	{
	}

CPinQModel::~CPinQModel()
	{
	iPinQTasks.ResetAndDestroy();
	iPinQTasks.Close();
	iPinQCategories.Close();
	
	delete iDeletedTask;
	}

CPinQTask& CPinQModel::Task(TUid aPinQTaskId) const
	{
	const TInt index = FindTaskIndexFromPinQUid(aPinQTaskId);
	ASSERT(index > KErrNotFound);
	return *(iPinQTasks[index]);
	}
//addnew task if it is needed
TUid CPinQModel::UpdatePrefL(TUid aUid)
	{
	if (aUid==NewTaskUid())
		{
		CPinQTask* task=CPinQTask::NewL(iTempPref);
		iTempPref.Reset();
		aUid=NewUniqueUid();
		task->SetUid(aUid);
		iPinQTasks.AppendL(task);
		}

	iDirty = ETrue;
	return aUid;
	}

void CPinQModel::RemoveTask(TInt aIndex,TBackup aBackup)
	{
	ASSERT(aIndex > KErrNotFound);
	if(iDeletedTask)
		{
		delete iDeletedTask; iDeletedTask = NULL;
		}
	if (aBackup==EBackup) iDeletedTask = &Task(aIndex);
	iPinQTasks.Remove(aIndex);
	iDirty = ETrue;
	}

void CPinQModel::RemoveTask(TUid aUid,TBackup aBackup)
	{
	const TInt index = FindTaskIndexFromPinQUid(aUid);
	RemoveTask(index,aBackup);
	}

void CPinQModel::RecoverDeletedTaskL()
	{
	if(iDeletedTask)
		{
		iPinQTasks.AppendL(iDeletedTask);
		iDeletedTask = NULL;
		iDirty = ETrue;
		}
	}

TInt CPinQModel::FindTaskIndexFromPinQUid(const TUid& aUid) const
	{
	const TInt count = iPinQTasks.Count();
	for(TInt index = 0; index < count; index++)
		{
		if(iPinQTasks[index]->Uid() == aUid)
			{
			return index;
			}
		}
	return KErrNotFound;
	}

void CPinQModel::StoreL(RWriteStream& aStream) const
	{

	const TInt count = iPinQTasks.Count();
	aStream.WriteInt32L(count);
	
	for(TInt index = 0; index < count; index++)
		iPinQTasks[index]->ExternalizeL(aStream);
		
	const TInt categoryCount = iPinQCategories.Count();
	aStream.WriteInt32L(categoryCount);
	
	for(TInt index = 0; index < categoryCount; index++)
		{
		iPinQCategories[index].ExternalizeL(aStream);
		}

	const_cast<CPinQModel*>(this)->iDirty = EFalse;
	}

void CPinQModel::RestoreL(RReadStream& aStream)
	{
	TInt count = aStream.ReadInt32L();
	while(count--)
		{
		CPinQTask* task = CPinQTask::NewLC();
		task->InternalizeL(aStream);
		iPinQTasks.AppendL(task);
		CleanupStack::Pop(task);
		}

	count = aStream.ReadInt32L();
	if(count > 0)
		{
		while(count--)
			{
			TPinQCategory category;
			category.InternalizeL(aStream);
			AddCategory(category);
			}
		}

	}

void CPinQModel::AddCategory(const TQikCategoryName& aCategoryName, TInt& aHandle)
	{
	TPinQCategory category;
	category.SetCategoryHandle(aHandle);
	category.SetCategoryName(aCategoryName);
	iPinQCategories.Append(category);
	iDirty = ETrue;
	}
	
void CPinQModel::RenameCategory(const TInt aHandle, const TDesC& aNewName)
	{
	const TInt count = iPinQCategories.Count();
	for(TInt index = 0; index < count; index++)
		{
		if(iPinQCategories[index].CategoryHandle() == aHandle)
			{
			iPinQCategories[index].SetCategoryName(aNewName);
			iDirty = ETrue;
			break;
			}
		}
	}

void CPinQModel::RemoveCategory(const TInt aHandle)
	{
	const TInt count = iPinQCategories.Count();
	for(TInt index = 0; index < count; index++)
		{
		if(iPinQCategories[index].CategoryHandle() == aHandle)
			{
			iPinQCategories.Remove(index);
			iDirty = ETrue;
			break;
			}
		}
	CategoryRemoved(aHandle);
	}

	

void CPinQModel::CategoryRemoved(TInt aHandle)
	{
	const TInt itemCount = TaskCount();
	for(TInt index = 0; index < itemCount; index++)
		{
		CPinQTask& item = Task(index);
		if(item.Pref().Category() == aHandle)
			{
			item.Pref().SetCategory(EPinQCategoryUnfiled);
			}
		}
	if(iDeletedTask && ( iDeletedTask->Pref().Category() == aHandle))
		{
		iDeletedTask->Pref().SetCategory(EPinQCategoryUnfiled);
		}		
	}

TBool CPinQModel::CategoryExists(TInt aHandle)
	{
	// Always return ETrue for default categories
	if (aHandle == EPinQCategoryUnfiled)
		{
		return ETrue;
		}
	
	const TInt count = iPinQCategories.Count();
	for(TInt index = 0; index < count; index++)
		{
		if(iPinQCategories[index].CategoryHandle() == aHandle)
			{
			return ETrue;
			}
		}
	return EFalse;
	}

TUid CPinQModel::NewUniqueUid()
	{
	TUid uid;
	uid.iUid = 1;

	const TInt count = iPinQTasks.Count();
	for(TInt index = 0; index < count; index++)
		{
		if(iPinQTasks[index]->Uid().iUid > uid.iUid)
			{
			uid.iUid = iPinQTasks[index]->Uid().iUid;
			}
		}
	if(iDeletedTask && iDeletedTask->Uid().iUid > uid.iUid)
		{
		uid.iUid = iDeletedTask->Uid().iUid;
		}
	uid.iUid++;
	return uid;
	}
// vim: ts=2:sw=2
